﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace LinuxTools
{

    public partial class Form1 : Form
    {
        public static List<HostInfo> hosts = null;
        Utils.SSH SSH;
        Utils.Key KeyTools;
        public Form1()
        {
            InitializeComponent();
            //Control.CheckForIllegalCrossThreadCalls = false;
            SSH = new Utils.SSH();
            KeyTools = new Utils.Key();
        }

        private void btnChangePWD_Click(object sender, EventArgs e)
        {
            string NewPassword = tbPassword.Text.Trim();
            if (string.IsNullOrEmpty(NewPassword))
            {
                MessageBox.Show("密码不能为空");
                return;
            }
            var hostInfoList = getHostInfoList();
            var selectedList = getSelectedIndex();
            tbResult.Clear();
            Task.Run(() =>
            {
                Parallel.For(0, selectedList.Count, new ParallelOptions { MaxDegreeOfParallelism = 4 }, i =>
                {
                    var idx = selectedList[i];
                    var hostItem = (HostInfo)hostInfoList[idx];
                    var _result = SSH.SSHChangePassword(hostItem.IP, hostItem.User, hostItem.Password, 22, NewPassword);
                    tbResult.Invoke((MethodInvoker)delegate
                    {
                        tbResult.AppendText($"{hostItem.IP}{(_result ? "修改成功" : "修改失败")}\r\n");
                    });
                    this.dataGridView1.Rows[idx].Cells[6].Value = (_result ? "修改成功" : "修改失败");
                });
                MessageBox.Show("检测完毕");
            });
        }

        private List<HostInfo> getHostInfoList()
        {
            return hosts;
        }
        private void btnConnect_Click(object sender, EventArgs e)
        {
            string NewPassword = tbPassword.Text.Trim();
            var hostInfoList = getHostInfoList();
            var selectedList = getSelectedIndex();
            tbResult.Clear();
            Task.Run(() =>
            {
                Parallel.For(0, selectedList.Count, new ParallelOptions { MaxDegreeOfParallelism = 10 }, i =>
               {
                   var idx = selectedList[i];
                   testConnect((HostInfo)hostInfoList[idx], idx);
               });
                MessageBox.Show("检测完毕");
            });

        }
        private void testConnect(HostInfo _host, int idx)
        {
            var _result = SSH.SSHConnectTest(_host.IP, _host.User, _host.Password, 22);
            var text = "";
            if (_result != true)
            {
                text = $"{_host.IP}不可连接\r\n";
                tbResult.Invoke((MethodInvoker)delegate
                {
                    tbResult.AppendText(text);
                });
                this.dataGridView1.Rows[idx].Cells[6].Value = "连接失败";
                this.dataGridView1.Rows[idx].Cells[6].Style.ForeColor = Color.Red;
            }
            else
            {
                this.dataGridView1.Rows[idx].Cells[6].Value = "连接成功";
                this.dataGridView1.Rows[idx].Cells[6].Style.ForeColor = Color.Green;
            }
        }
        private void btnCreateKey_Click(object sender, EventArgs e)
        {
            Tuple<string, string> tup = KeyTools.GenKey();

            Utils.FileTools.WriteFile(tup.Item1, "id_rsa.pub");
            Utils.FileTools.WriteFile(tup.Item2, "id_rsa");
            tbAuthResult.AppendText(tup.Item1);
            tbAuthResult.AppendText(tup.Item2);
            labelKeyPosition.Text = "已成生当前目录下 id_ras 及id_rsa.pub文件";
        }

        private void btnAuth_Click(object sender, EventArgs e)
        {
            var hostInfoList = getHostInfoList();
            string pubKey = Utils.FileTools.ReadFile("id_rsa.pub");
            tbAuthResult.Clear();

            var selectedList = getSelectedIndex();
            Task.Run(() =>
            {
                Parallel.For(0, selectedList.Count, new ParallelOptions { MaxDegreeOfParallelism = 4 }, i =>
                {
                    var idx = selectedList[i];
                    var hostItem = (HostInfo)hostInfoList[idx];
                    var _result = SSH.SendKey(hostItem.IP, hostItem.User, hostItem.Password, 22, pubKey);
                    var text = $"{hostItem.IP}{(_result ? "免密成功" : "免密失败")}\r\n";
                    tbAuthResult.Invoke((MethodInvoker)delegate
                    {
                        tbAuthResult.AppendText(text);
                    });
                    this.dataGridView1.Rows[idx].Cells[6].Value = (_result ? "免密成功" : "免密失败");
                });
                MessageBox.Show("操作完成");
            });
        }

        private void btnAuthTest_Click(object sender, EventArgs e)
        {
            var hostInfoList = getHostInfoList();
            tbAuthResult.Clear();
            string pubKey = Utils.FileTools.ReadFile("id_rsa");
            var selectedList = getSelectedIndex();
            Task.Run(() =>
            {
                Parallel.For(0, selectedList.Count, new ParallelOptions { MaxDegreeOfParallelism = 4 }, i =>
                {
                    var idx = selectedList[i];
                    var hostItem = (HostInfo)hostInfoList[idx];
                    var _result = SSH.ConnectByKey(hostItem.IP, hostItem.User, "id_rsa", 22);
                    var text = $"{hostItem.IP}{(_result ? "免密成功" : "免密失败")}\r\n"; ;
                    tbAuthResult.Invoke((MethodInvoker)delegate
                    {
                        tbAuthResult.AppendText(text);
                    });
                    this.dataGridView1.Rows[idx].Cells[6].Value = (_result ? "免密成功" : "免密失败");
                });
                MessageBox.Show("检测完毕");
            });
        }

        private void btnFilePicker_Click(object sender, EventArgs e)
        {
            ofdUpload.Multiselect = false;//该值确定是否可以选择多个文件
            ofdUpload.Title = "请选择文件";
            ofdUpload.Filter = "所有文件(*.*)|*.*";
            if (ofdUpload.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                labelSelectResult.Text = $"文件路径:{ofdUpload.FileName}";
            }
        }

        private void btnExecute_Click(object sender, EventArgs e)
        {
            var hostInfoList = getHostInfoList();
            tbAuthResult.Clear();
            var selectedList = getSelectedIndex();
            Task.Run(() =>
            {
                Parallel.For(0, selectedList.Count, new ParallelOptions { MaxDegreeOfParallelism = 5 }, i =>
                {
                    var idx = selectedList[i];
                    var hostItem = (HostInfo)hostInfoList[idx];
                    SSH.SSHExec(hostItem.IP, hostItem.User, hostItem.Password, 22, tbExec.Text, (result) =>
                    {
                        tbExecuteResult.Invoke((MethodInvoker)delegate
                        {
                            tbExecuteResult.AppendText(result + Environment.NewLine);
                            this.dataGridView1.Rows[idx].Cells[6].Value = result;
                        });
                    });

                });
            });
        }

        private void btnImport_Click(object sender, EventArgs e)
        {
            FormHosts formHosts = new FormHosts();
            if (formHosts.ShowDialog() == DialogResult.OK)
            {
                PrepareHostList();
            }
        }
        private void PrepareHostList()
        {
            dataGridView1.Rows.Clear();
            dataGridView1.Refresh();
            //导入到datagridview
            for (int i = 0; i < hosts.Count; i++)
            {
                int index = this.dataGridView1.Rows.Add();
                this.dataGridView1.Rows[i].Cells[1].Value = (index + 1).ToString();
                this.dataGridView1.Rows[i].Cells[2].Value = hosts[i].IP;
                this.dataGridView1.Rows[i].Cells[3].Value = "22";
                this.dataGridView1.Rows[i].Cells[4].Value = hosts[i].User;
                this.dataGridView1.Rows[i].Cells[5].Value = hosts[i].Password;
            }
        }
        public void AddFullSelect()
        {
            // if (dataGridView1.Rows.Count < 1)
            // {
            //     return;
            // }
            System.Windows.Forms.CheckBox ckBox = new System.Windows.Forms.CheckBox();
            ckBox.Text = "全选";
            //ckBox.AutoSize = true;
            ckBox.Checked = false;
            System.Drawing.Rectangle rect =
            dataGridView1.GetCellDisplayRectangle(0, -1, true);
            ckBox.Size = new System.Drawing.Size(dataGridView1.Columns[0].Width, 23);
            rect.X = rect.X + 3;
            rect.Y = rect.Y + 3;
            ckBox.Location = rect.Location;
            ckBox.CheckedChanged += new EventHandler(ckBox_CheckedChanged);
            dataGridView1.Controls.Add(ckBox);
        }
        void ckBox_CheckedChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                dataGridView1.Rows[i].Cells[0].Value = ((System.Windows.Forms.CheckBox)sender).Checked;
            }
            dataGridView1.EndEdit();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.dataGridView1.Columns["IP"].Width = 260;
            this.dataGridView1.Columns["Status"].Width = 400;
            this.dataGridView1.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellDoubleClick);

            AddFullSelect();
            hosts = Util.getHostInfoList(Util.ReadHostFile());
            dataGridView1.ReadOnly = false;
            foreach (DataGridViewColumn c in dataGridView1.Columns)
            {
                c.ReadOnly = true;
                if (c.Index == 0)
                {
                    c.ReadOnly = false;  // editable
                }
            }
            PrepareHostList();
        }
        private List<int> getSelectedIndex()
        {
            List<int> lists = new List<int>();
            for (int i = 0; i < dataGridView1.RowCount; i++)
            {
                if (dataGridView1.Rows[i].Cells[0].EditedFormattedValue.ToString() == "True")
                {
                    lists.Add(i);
                }
            }
            return lists;
        }

        private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            Debug.WriteLine("click one");
            var rowIndex = e.RowIndex;
            var ip = (string)dataGridView1.Rows[rowIndex].Cells["IP"].Value;
            var user = (string)dataGridView1.Rows[rowIndex].Cells["User"].Value;
            var passwd = (string)dataGridView1.Rows[rowIndex].Cells["Password"].Value;
            var port = 22;
            try
            {
                port = Convert.ToInt32(dataGridView1.Rows[rowIndex].Cells["Port"].Value);
            }
            catch (Exception ex)
            {

            }
            SSH.CallPutty(ip, user, passwd, port);
        }

        private void btnFileUpload_Click(object sender, EventArgs e)
        {
            var hostInfoList = getHostInfoList();
            tbTransferResult.Clear();
            var selectedList = getSelectedIndex();
            if (selectedList.Count < 1)
            {
                MessageBox.Show("请选择主机");
            }
            if (string.IsNullOrEmpty( ofdUpload.SafeFileName))
            {
                MessageBox.Show("请选择文件");
            }
            Task.Run(() =>
            {
                Parallel.For(0, selectedList.Count, new ParallelOptions { MaxDegreeOfParallelism = 5 }, i =>
                {
                    var idx = selectedList[i];
                    var hostItem = (HostInfo)hostInfoList[idx];
                    var result = SSH.Upload(hostItem.IP, hostItem.User, hostItem.Password, 22, ofdUpload.FileName, $"{ofdUpload.SafeFileName}");
                    tbTransferResult.Invoke((MethodInvoker)delegate
                    {
                        if (result) {
                            tbTransferResult.AppendText($"{hostItem.IP}上传成功" + Environment.NewLine);
                        } else
                        {
                            tbTransferResult.AppendText($"{hostItem.IP}上传失败" + Environment.NewLine);
                        }
                        
                        this.dataGridView1.Rows[idx].Cells[6].Value = result;
                    });

                });
            });
        }
    }
}
